package com.wyman.beans.factory.annotation;

import com.wyman.beans.BeanException;
import com.wyman.beans.PropertyValues;
import com.wyman.beans.factory.BeanFactory;
import com.wyman.beans.factory.BeanFactoryAware;
import com.wyman.beans.factory.ConfigurableListableBeanFactory;
import com.wyman.beans.factory.config.InstantiationAwareBeanPostProcessor;

import cn.hutool.core.bean.BeanUtil;

import java.lang.reflect.Field;

/**
 * @Author 李伟民
 * @Description
 * @DateTime 2024/12/30 15:39
 */
//如果有context注解 这个类才会被注册到容器中发挥作用 在xmlReader中判断是否有注解  在ClassPathBeanDefinitionScanner中将它注入容器
public class AutowiredAnnotationBeanPostProcessor implements BeanFactoryAware, InstantiationAwareBeanPostProcessor {

    private ConfigurableListableBeanFactory beanFactory;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeanException {
            this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
    }

    //处理@Value和@@Autowired注解 将注解的中的属性值注入到bean中
    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, Object bean, String beanName) throws BeanException {

        //要处理 @Autowired 和 @Value注解
        Class<?> clazz = bean.getClass();
        Field[] fields = clazz.getDeclaredFields();

        for(Field field:fields){
            field.setAccessible(true);
            Value value = field.getAnnotation(Value.class);
            if(value!=null){
                String valueStr = value.value();
                //使用字符解析器 将配置文件中的和${key}对应的key的值注入到属性中
                String propValue = beanFactory.resolveEmbeddedValue(valueStr);
                try {
                    field.set(bean,propValue);
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                }

            }
        }


        for(Field field:fields){
            field.setAccessible(true);
            Autowired autowired = field.getAnnotation(Autowired.class);
            if(autowired!=null){
                Class<?> fieldType = field.getType();
                Qualifier qualifier = field.getAnnotation(Qualifier.class);
                Object dependentBean = null;
                String dependBeanName = null;
                if(qualifier!=null){
                    dependBeanName = qualifier.value();
                    dependentBean = beanFactory.getBean(dependBeanName);
                }
                else {
                    dependentBean = beanFactory.getBean(fieldType);
                }
                BeanUtil.setFieldValue(bean, field.getName(), dependentBean);
            }
        }

        int a=0;
        System.out.println(bean);

        return pvs;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) {
        return true;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeanException {
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeanException {
        return bean;
    }


    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeanException {
        return null;
    }
}
